﻿using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Sunny.Entity;
using Sunny.Model;
using Sunny.Model.RedisCache;
using Sunny.Model.Vo;
using Sunny.Service;
using Sunny.Util.Exception;

namespace Sunny.Api.Interceptors
{
    public class AutoFillInterceptor : SaveChangesInterceptor
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly RedisService _redisService;

        public AutoFillInterceptor(IHttpContextAccessor httpContextAccessor, RedisService redisService)
        {
            _httpContextAccessor = httpContextAccessor;
            _redisService = redisService;
        }

        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            var token = _httpContextAccessor.HttpContext?.Request.Headers[Constants.Token].ToString();
            if (string.IsNullOrEmpty(token))
            {
                return base.SavingChangesAsync(eventData, result, cancellationToken);
            }
            var loginUser = _redisService.Get<LoginUser>(UserKeyPrefix.Info, token);
            
            var entityEntries = eventData.Context.ChangeTracker.Entries();
            foreach (var entityEntry in entityEntries)
            {
                
                if (entityEntry.Entity is IAutoFill autoFillEntity)
                {
                    switch (entityEntry.State)
                    {
                        case EntityState.Added:
                            autoFillEntity.CreateBy = loginUser.UserName;
                            autoFillEntity.CreateTime = DateTime.Now;
                            break;
                        case EntityState.Modified:
                            autoFillEntity.UpdateBy = loginUser.UserName;
                            autoFillEntity.UpdateTime = DateTime.Now;
                            break;
                    }
                }

            }
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }
    }
}